﻿using FreeDream.Common;
using FreeDream.IService;
using FreeDream.Model;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;

namespace FreeDream.WebApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class SecurityController : ControllerBase
    {
        private readonly ILogger<SecurityController> _logger;
        private readonly IHttpClientService _httpClientService;

        public SecurityController(ILogger<SecurityController> logger, IHttpClientService httpClientService)
        {
            _logger = logger;
            _httpClientService = httpClientService;
        }

        #region 测试

        /// <summary>
        /// 测试
        /// </summary>
        /// <returns></returns>
        [HttpGet, Route("GetDate")]
        [Authorize]
        public async Task<string> TestDate()
        {
            _logger.LogInformation($"测试。。。{DateTime.Now}...");
            return $"测试。。。{DateTime.Now}...";
        }

        /// <summary>
        /// 测试RawData
        /// </summary>
        /// <returns></returns>
        [HttpGet, Route("TestRawData")]
        public async Task<string> TestRawData(string rawData, string session_key, string signature)
        {
            //1.auth.code2Session 获取到openid，session_key
            //2.wx.getUserInfo 获取到rawData signature encryptedData iv
            if (string.IsNullOrWhiteSpace(rawData))
            {
                //rawData = JsonConvert.SerializeObject(new
                //{
                //    nickName = "Band",
                //    gender = 1,
                //    language = "zh_CN",
                //    city = "Guangzhou",
                //    province = "Guangdong",
                //    country = "CN",
                //    avatarUrl = "http://wx.qlogo.cn/mmopen/vi_32/1vZvI39NWFQ9XM4LtQpFrQJ1xlgZxx3w7bQxKARol6503Iuswjjn6nIGBiaycAjAtpujxyzYsrztuuICqIM5ibXQ/0"
                //});
                rawData = JsonConvert.SerializeObject(new
                {
                    nickName = "没英文名不如Siri好了",
                    gender = 0,
                    language = "zh_CN",
                    city = "",
                    province = "",
                    country = "",
                    avatarUrl = "https://thirdwx.qlogo.cn/mmopen/vi_32/B6zr7W1oDcVzMQOf7qPg3K1UgcYLVCdGCmJPkZicRo4xribsx3dq4tfzjkKuNQ4Aiacz3C11wC8LPe2ESudlBUm9w/132"
                });

            }
            if (string.IsNullOrWhiteSpace(session_key))
            {
                //session_key = "HyVFkGl5F5OQWJZZaNzBBg==";
                session_key = "CyN0jwtNW18R4NuTBI0gXQ==";
            }
            if (string.IsNullOrWhiteSpace(signature))
            {
                //signature = "75e81ceda165f4ffa64f4068af58c64b8f54b88c";
                signature = "e9c02ca3a92e94791f189895116570f66947b3a4";
            }

            var generateSignature = StringSecurity.Sha1Encryption($"{rawData}{session_key}");
            //var pwd = "{\"nickName\":\"Band\",\"gender\":1,\"language\":\"zh_CN\",\"city\":\"Guangzhou\",\"province\":\"Guangdong\",\"country\":\"CN\",\"avatarUrl\":\"http://wx.qlogo.cn/mmopen/vi_32/1vZvI39NWFQ9XM4LtQpFrQJ1xlgZxx3w7bQxKARol6503Iuswjjn6nIGBiaycAjAtpujxyzYsrztuuICqIM5ibXQ/0\"}HyVFkGl5F5OQWJZZaNzBBg==";
            //var generateSignature = StringSecurity.Sha1Encryption(pwd);
            var blnDiff = (signature == generateSignature);

            _logger.LogInformation($"测试TestRawData。。。{DateTime.Now}...{blnDiff}...{signature},{generateSignature}");

            return $"测试TestRawData。。。{DateTime.Now}...{blnDiff}...{signature},{generateSignature}";
            //return await Task.FromResult($"测试。。。{DateTime.Now}...{blnDiff}...{signature},{generateSignature}");
        }

        /// <summary>
        /// TestEncryptedData
        /// </summary>
        /// <param name="encryptedData"></param>
        /// <param name="sessionKey"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        [HttpGet, Route("TestEncryptedData")]
        public async Task<string> TestEncryptedData(string encryptedData, string sessionKey, string iv)
        {
            try
            {
                encryptedData =
                            "CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZM" +
                            "QmRzooG2xrDcvSnxIMXFufNstNGTyaGS" +
                            "9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+" +
                            "3hVbJSRgv+4lGOETKUQz6OYStslQ142d" +
                            "NCuabNPGBzlooOmB231qMM85d2/fV6Ch" +
                            "evvXvQP8Hkue1poOFtnEtpyxVLW1zAo6" +
                            "/1Xx1COxFvrc2d7UL/lmHInNlxuacJXw" +
                            "u0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn" +
                            "/Hz7saL8xz+W//FRAUid1OksQaQx4CMs" +
                            "8LOddcQhULW4ucetDf96JcR3g0gfRK4P" +
                            "C7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB" +
                            "6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns" +
                            "/8wR2SiRS7MNACwTyrGvt9ts8p12PKFd" +
                            "lqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYV" +
                            "oKlaRv85IfVunYzO0IKXsyl7JCUjCpoG" +
                            "20f0a04COwfneQAGGwd5oa+T8yO5hzuy" +
                            "Db/XcxxmK01EpqOyuxINew==";
                iv = "r7BXXKkLb8qrSNn05n0qiA==";
                sessionKey = "tiihtNczf5v6AKRyjwEUhQ==";
                //var result2 = StringSecurity.AesDecode(encryptedData, sessionKey, iv);
                var result = StringSecurity.AESEncrypt(encryptedData, sessionKey, iv);

                _logger.LogInformation($"测试TestEncryptedData。。。{DateTime.Now}...{result}");

                return $"测试TestEncryptedData。。。{DateTime.Now}...{result}";
            }
            catch (Exception ex)
            {

                throw;
            }
        }

        #endregion

        #region Sm4

        /// <summary>
        /// Sm4加密
        /// </summary>
        /// <param name="encryptedData"></param>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        [HttpGet, Route("Sm4Encrypted")]
        public async Task<ResponseModel> TestSm4Encrypted(string encryptedData, string key, string iv)
        {
            var response = new ResponseModel();
            try
            {
                if (string.IsNullOrWhiteSpace(encryptedData))
                {
                    response.SetParamError("encryptedData不能为空");
                    return response;
                }

                Sm4Crypto sm4Crypto = new Sm4Crypto();
                sm4Crypto.Data = encryptedData;

                if (!string.IsNullOrWhiteSpace(key))
                {
                    sm4Crypto.Key = key;
                }

                if (!string.IsNullOrWhiteSpace(iv))
                {
                    sm4Crypto.Iv = iv;
                }

                var result = sm4Crypto.Encrypt(sm4Crypto);

                response.Data = result;
                response.SetSuccess();

            }
            catch (Exception ex)
            {
                response.SetError(ex.StackTrace);
            }

            return response;
        }

        /// <summary>
        /// Sm4解密
        /// </summary>
        /// <param name="decryptedData"></param>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        [HttpGet, Route("Sm4Decrypt")]
        public async Task<ResponseModel> TestSm4Decrypt(string decryptedData, string key, string iv)
        {
            var response = new ResponseModel();
            try
            {
                if (string.IsNullOrWhiteSpace(decryptedData))
                {
                    response.SetParamError("encryptedData不能为空");
                    return response;
                }

                Sm4Crypto sm4Crypto = new Sm4Crypto();
                sm4Crypto.Data = decryptedData;

                if (!string.IsNullOrWhiteSpace(key))
                {
                    sm4Crypto.Key = key;
                }

                if (!string.IsNullOrWhiteSpace(iv))
                {
                    sm4Crypto.Iv = iv;
                }

                var result = sm4Crypto.Decrypt(sm4Crypto);

                response.Data = result;
                response.SetSuccess();

            }
            catch (Exception ex)
            {
                response.SetError(ex.StackTrace);
            }

            return response;
        }

        #endregion

        #region AES

        /// <summary>
        /// Aes加密
        /// </summary>
        /// <param name="decryptedData"></param>
        /// <returns></returns>
        [HttpGet, Route("AesEncrypt")]
        public async Task<string> TesAesEncrypt(string decryptedData)
        {
            string key = "9814548961710661";
            var res1 = StringSecurity.AesEncrypt(decryptedData, key);
            var res2 = StringSecurity.Encrypt(decryptedData, key);
            var bln = (res1 == res2);
            return $"{DateTime.Now}...{bln}....{res1},{res2}";
        }

        /// <summary>
        /// Aes解密
        /// </summary>
        /// <param name="decryptedData"></param>
        /// <returns></returns>
        [HttpGet, Route("AesDecrypt")]
        public async Task<string> TesAesDecrypt(string decryptedData)
        {
            string key = "9814548961710661";
            var res1 = StringSecurity.AesDecrypt(decryptedData, key);
            var res2 = StringSecurity.Decrypt(decryptedData, key);
            var bln = (res1 == res2);
            return $"{DateTime.Now}...{bln}....{res1},{res2}";

        }

        /// <summary>
        /// Aes加密解密
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpGet, Route("AesEnDecrype")]
        public async Task<string> TesAesEnDecrype(string data)
        {
            string key = "9814548961710661";
            var str = StringSecurity.AesEnDecrype(data, key);
            return $"{DateTime.Now}...{str}";
        }

        #endregion

        #region RSA

        /// <summary>
        /// 生成RSAKey
        /// </summary>
        /// <returns></returns>
        [HttpGet, Route("RSAKey")]
        public async Task<ResponseModel> TestGetRSAKey()
        {
            var response = new ResponseModel();
            try
            {
                var key = StringSecurity.GetKey();

                var result = key;

                response.Data = result;
                response.SetSuccess();

            }
            catch (Exception ex)
            {
                response.SetError(ex.StackTrace);
            }

            return response;
        }

        /// <summary>
        /// RSA加密数据
        /// </summary>
        /// <param name="strData"></param>
        /// <returns></returns>
        [HttpGet, Route("RSAEncryption")]
        public async Task<string> TestRSAEncryption(string strData)
        {
            var result = StringSecurity.RSAEncryption(strData);

            return await Task.FromResult(result);

        }

        /// <summary>
        /// RSA解密数据
        /// </summary>
        /// <param name="encryptionData"></param>
        /// <returns></returns>
        [HttpGet, Route("RSADecrypt")]
        public async Task<string> TestRSADecrypt(string encryptionData)
        {
            var result = StringSecurity.RSADecrypt(encryptionData);

            return await Task.FromResult(result);

        }

        #endregion

        #region 测试

        /// <summary>
        /// 测试时间
        /// </summary>
        /// <param name="unixTimeStamp">时间戳(s)</param>
        /// <returns></returns>
        [HttpGet, Route("TimeStamp")]
        public async Task<string> TestDate(long unixTimeStamp)
        {
            var startTime = TimeZoneInfo.Utc.ObjToDate(new DateTime(1970, 1, 1));   //1970/1/1 0:00:00
            var time1 = TimeZoneInfo.Local.ObjToDate(new DateTime(1970, 1, 1)); //1970/1/1 0:00:00
            DateTime dt1 = startTime.ToUniversalTime(); //1969/12/31 16:00:00
            DateTime dt2 = startTime.AddSeconds(unixTimeStamp);
            //1.时间戳
            long timeStamp = (long)(DateTime.Now - startTime).TotalMilliseconds;
            long ts = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
            //2.时间戳
            var start = new DateTime(1970, 1, 1) + TimeZoneInfo.Local.GetUtcOffset(DateTime.Now);   //1970/1/1 8:00:00
            var startTime2 = TimeZoneInfo.ConvertTime(start, TimeZoneInfo.FindSystemTimeZoneById(TimeZoneInfo.Local.Id));   //1970/1/1 8:00:00
            var startTime3 = TimeZoneInfo.ConvertTime(DateTime.Now, TimeZoneInfo.FindSystemTimeZoneById(TimeZoneInfo.Local.Id));

            var timeStamp2 = (long)(startTime3 - startTime2).TotalSeconds;

            //时间转时间戳
            var dt5 = startTime2.AddSeconds(unixTimeStamp);

            DateTime dt3 = DateTime.ParseExact("20220916210701", "yyyyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture);
            DateTime dt4 = DateTimeOffset.FromUnixTimeSeconds(unixTimeStamp).LocalDateTime;//时间戳转本地时间-时间戳精确到秒

            var ts2 = new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds();//时间转时间戳Unix-时间戳精确到秒

            return await Task.FromResult($"{dt5},{dt4}");
        }

        /// <summary>
        /// 转换数据
        /// </summary>
        /// <param name=""></param>
        /// <returns></returns>
        [HttpGet, Route("TestJsonStr")]
        public async Task<ResponseModel> TestJsonStr()
        {
            var response = new ResponseModel();
            try
            {
                //RealNameVerifySetting realNameVerifySetting = new RealNameVerifySetting();
                //AppSettings.Bind("RealNameVerify", realNameVerifySetting);

                var resultData = "{\"data\":{\"YWSLID\":\"224012021040911010111\"},\"success\":true,\"title\":\"200\",\"detail\":\"[{“CardNo”:”454544199910108978”,“result”：”实名认证成功”，“Code”:200}]\"}";
                var resultObj = Newtonsoft.Json.Linq.JObject.Parse(resultData.ToString());
                if (Convert.ToBoolean(resultObj["success"]) && resultObj["title"].ToString() == "200")
                {
                    var detail = Newtonsoft.Json.Linq.JArray.FromObject(resultObj["detail"])[0];
                    if (detail != null && GetPropertyValue(detail, "code").ToString() == "200")
                    {
                        response.SetSuccess("实名认证成功");
                    }
                    else
                    {
                        response.SetError($"认证失败:code:{GetPropertyValue(detail, "code")}");
                    }
                }
                else
                {
                    response.SetError($"认证失败:异常码{GetPropertyValue(resultObj, "title")}");
                }

                //var ioControlOperation = JsonConvert.DeserializeObject<IoControlOperation>(json);
                ////var str1 = Newtonsoft.Json.Linq.JObject.Parse(ioControlOperation.BusinessData);
                //var noAppointment = JsonConvert.DeserializeObject<NoAppointment>(ioControlOperation.BusinessData);

                var res = JsonConvert.SerializeObject(new { code = "5", category = "", name = "" });

                response.Data = res;
            }
            catch (Exception ex)
            {

                throw;
            }

            return response;
        }

        private object GetPropertyValue(object info, string field)
        {
            if (info == null) return null;
            Type t = info.GetType();
            IEnumerable<System.Reflection.PropertyInfo> property = from pi in t.GetProperties() where pi.Name.ToLower() == field.ToLower() select pi;
            return property.First().GetValue(info, null);
        }

        #endregion

    }
}
